<?php
namespace EasyVote\EasyVoteBundle\Command;

use EasyVote\EasyVoteBundle\Entity\Election;
use EasyVote\EasyVoteBundle\Entity\User;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\StringInput;
use Doctrine\Common\Collections\ArrayCollection;
use DateTime;

class ElectionReminderCommand extends ContainerAwareCommand
{
    private $output;

    /**
     * prepares the command
     */
    protected function configure()
    {
        $this
            ->setName('easyvotebundle:electionreminders:run')
            ->setDescription('Runs Election Reminder Email Tasks if needed');
    }

    /**
     * executes the command
     * @param InputInterface $input
     * @param OutputInterface $output
     * @return int|null|void
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $output->writeln('<comment>Running Election Reminder Email Tasks...</comment>');

        $this->output = $output;
        $em = $this->getContainer()->get('doctrine.orm.entity_manager');

        //get the reminders
        $reminderTasks = $em->createQuery('SELECT er FROM EasyVoteBundle:ElectionReminder er WHERE er.reminderTime <= :curr_time')->setParameter('curr_time', new DateTime())->getResult();

        //iterate through tasks
        foreach ($reminderTasks as $reminderTask) {
            $usersToSend = $this->getUsers($reminderTask->getElection(), $em);

            $this->filterUsers($reminderTask->getElection(), $em, $usersToSend);

            foreach ($usersToSend as $user) {
                $this->sendReminderEmail($user, $reminderTask->getElection());
            }

            $reminderTask->getElection()->removeReminder($reminderTask);
            $em->persist($reminderTask->getElection());
            $em->flush();
            $em->remove($reminderTask);

        }

        // Flush database changes
        $em->flush();

        $output->writeln('<comment>Done!</comment>');
    }

    /**
     * Gets the users that have NOT voted in an election
     * @param Election $election the election
     * @param Object $em the entity manager
     * @return Object the array or arraycollection of users that have NOT voted.
     */
    private function getUsers($election, $em)
    {
        return $em->createQuery('SELECT u FROM EasyVoteBundle:User u ' .
            'WHERE u.id NOT IN ' .
            '( SELECT us.id FROM EasyVoteBundle:Vote v INNER JOIN v.election e INNER JOIN v.user us WHERE e.id = :election_id )')
            ->setParameter('election_id', $election->getID())->getResult();

    }

    /**
     * Removes users that are ineligible to vote from consideration when sending reminder emails.
     * @param Election $election the election
     * @param Object $em the entity manager
     * @param Object $users_arr the array or arraycollection made by getUsers()
     */
    private function filterUsers($election, $em, $users_arr)
    {
        //cassie, do filtering for eligibility stuff here.
    }

    /**
     * Sends a reminder email to the user
     * @param User $user The user to email
     * @param Election $election The election to email about
     */
    private function sendReminderEmail(User $user, Election $election)
    {
        $message = \Swift_Message::newInstance()
            ->setSubject('Vote in \'' . $election->getTitle(). '\'')
            ->setContentType('text/html')
            ->addFrom($this->getContainer()->getParameter('mailer_user'))
            ->addReplyTo($this->getContainer()->getParameter('mailer_user'))
            ->setBody($this->getContainer()->get('templating')->render('EasyVoteBundle:Email:default.html.twig', array(
                'user' => $user, 'election' => $election
            )));
        foreach($user->getEmails() as $email){
            $message = $message->addTo($email->getValue());
        }
        //$this->output->writeln($message->toString());

        $this->getContainer()->get('mailer')->send($message);
    }
}